using System;
using System.Diagnostics;
using System.Data;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
using System.Text;

using MSHelpLib.BaseCode;

namespace MSHelpLib
{	
	#region Enums
    /// <summary>
    /// 
    /// </summary>
	public enum PAFEnum 
    {
        /// <summary>
        /// 
        /// </summary>
        Continue,
        /// <summary>
        /// 
        /// </summary>
        Abort
    };

	/// <summary>
	/// Enumeration for specifying the index type
	/// </summary>
	public enum IndexType
	{
        /// <summary>
        /// 
        /// </summary>
		None=0,
		/// <summary>
		/// Keyword links should be used
		/// </summary>
		KeywordLinks = 1,
		/// <summary>
		/// Associative links should be used
		/// </summary>
		AssociativeLinks =  2
	}	
	#endregion
		
	#region Events
    /// <summary>
    /// 
    /// </summary>
	public delegate void StatusHandler(int Level,string Info);
    /// <summary>
    /// 
    /// </summary>
	public delegate void ProgressHandler(int Value, int MaxValue);
    /// <summary>
    /// 
    /// </summary>
	public delegate PAFEnum ProcessAllFilesDelegate(IFileInfo fileInfo);
	#endregion

    /// <summary>
    /// 
    /// </summary>
	public interface IFileInfo 
	{
        /// <summary>
        /// Gets or sets the help stream.
        /// </summary>
        /// <value>The help stream.</value>
		IHelpStream	HelpStream	{ get; set; }
        /// <summary>
        /// Gets the name of the file.
        /// </summary>
        /// <value>The name of the file.</value>
		string		FileName	{ get; }
        /// <summary>
        /// Gets the URL.
        /// </summary>
        /// <value>The URL.</value>
		string		URL			{ get; }
        /// <summary>
        /// Gets the offset.
        /// </summary>
        /// <value>The offset.</value>
		UInt64		Offset		{ get; }
        /// <summary>
        /// Gets the length.
        /// </summary>
        /// <value>The length.</value>
		UInt64		Length		{ get; }
        /// <summary>
        /// Gets the stream.
        /// </summary>
        /// <value>The stream.</value>
		UInt16		Stream		{ get; }
	}

    /// <summary>
    /// 
    /// </summary>
	public interface IHelpSystem
	{
        /// <summary>
        /// Occurs when [status handler event].
        /// </summary>
		event StatusHandler StatusHandlerEvent;
        /// <summary>
        /// Occurs when [progress handler event].
        /// </summary>
		event ProgressHandler ProgressHandlerEvent;

        /// <summary>
        /// Opens the specified file name.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		IHelpFile			Open(string FileName);
        /// <summary>
        /// Opens the specified file name.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="Flags">The flags.</param>
        /// <returns></returns>
		IHelpFile			Open(string FileName, int Flags);
        /// <summary>
        /// Closes this instance.
        /// </summary>
		void				Close();
		
		/// <summary>
		/// Readonly property which holds the number of files contained in CHM/HXS files loaded
		/// </summary>
		int					NumberOfFiles		{ get; }

        /// <summary>
        /// Readonly property which holds the number of CHM/HXS files loaded
        /// </summary>
        /// <value>The files loaded.</value>
		int					FilesLoaded			{ get; }

        /// <summary>
        /// Gets the help file.
        /// </summary>
        /// <param name="i">The i.</param>
        /// <returns></returns>
		IHelpFile			GetHelpFile(int i);
        /// <summary>
        /// Gets the or load help file.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		IHelpFile			GetOrLoadHelpFile(string FileName);

        /// <summary>
        /// Gets a value indicating whether this instance has table of contents.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has table of contents; otherwise, <c>false</c>.
        /// </value>
		bool				HasTableOfContents	{ get; }
        /// <summary>
        /// Gets the table of contents.
        /// </summary>
        /// <value>The table of contents.</value>
		TableOfContents		TableOfContents		{ get; }

        /// <summary>
        /// Gets or sets the flags.
        /// </summary>
        /// <value>The flags.</value>
        int                 Flags               { get; set;}
        /// <summary>
        /// Gets a value indicating whether this instance has index.
        /// </summary>
        /// <value><c>true</c> if this instance has index; otherwise, <c>false</c>.</value>
		bool				HasIndex			{ get; }
        /// <summary>
        /// Gets the index.
        /// </summary>
        /// <value>The index.</value>
		Index				Index				{ get; }
        /// <summary>
        /// Gets the type of the help index.
        /// </summary>
        /// <value>The type of the help index.</value>
		IndexType			HelpIndexType		{ get; }

        /// <summary>
        /// Gets a value indicating whether this instance can search.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance can search; otherwise, <c>false</c>.
        /// </value>
		bool				CanSearch			{ get; }
        /// <summary>
        /// Inits the search.
        /// </summary>
		void				InitSearch();
        /// <summary>
        /// Performs the search.
        /// </summary>
        /// <param name="Words">The words.</param>
        /// <returns></returns>
		SearchResultsTable PerformSearch(string Words);

        /// <summary>
        /// Finds the file.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		IFileInfo			FindFile(string FileName);
        /// <summary>
        /// Finds the file.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="HelpFile">The help file.</param>
        /// <returns></returns>
		IFileInfo			FindFile(string FileName, IHelpFile HelpFile);
        /// <summary>
        /// Extracts the specified file info.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
		MemoryStream		Extract(IFileInfo fileInfo);
        /// <summary>
        /// Extracts as text.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
		string				ExtractAsText(IFileInfo fileInfo);

        /// <summary>
        /// Processes all files.
        /// </summary>
        /// <param name="processAllFiles">The process all files.</param>
        /// <returns></returns>
		int 				ProcessAllFiles(ProcessAllFilesDelegate processAllFiles);

        /// <summary>
        /// Called when [status].
        /// </summary>
        /// <param name="Level">The level.</param>
        /// <param name="Text">The text.</param>
		void				OnStatus(int Level, string Text);
        /// <summary>
        /// Called when [status].
        /// </summary>
        /// <param name="Text">The text.</param>
		void				OnStatus(string Text);
        /// <summary>
        /// Called when [progress].
        /// </summary>
        /// <param name="Value">The value.</param>
        /// <param name="MaxValue">The max value.</param>
		void				OnProgress(int Value, int MaxValue);
	}

    /// <summary>
    /// 
    /// </summary>
	[FlagsAttribute]
	public enum LoadFlags 
	{
		/// <summary>
		/// Only load System Data, IE. No Index or TOC
		/// </summary>		
		LoadOnlySystemData=1,

		/// <summary>
		/// Load data from Dump File. If this is not defined then load data in normal way
		/// </summary>
		LoadDumpFile=2,

		/// <summary>
		/// Save Dump data to file to allow fast loading in future.
		/// </summary>
		SaveDumpFile=4,

		/// <summary>
		/// Create Search Index data on first load
		/// </summary>
		CreateSearchIndexOnLoad=8,

		/// <summary>
		/// Create Search Index Data on first use and then save to Dump File.
		/// </summary>
		CreateSearchIndexOnFirstUseAndSave=16,

		/// <summary>
		/// Wipe the temp directory before processing a page
		/// </summary>
		WipeTempDir=32,

        /// <summary>
        /// Remove XML tags from HTML Code
        /// </summary>
		RemoveXMLTags=64,

        /// <summary>
        /// Remove Script Tags from HTML code
        /// </summary>
		RemoveScriptTags=128,

        /// <summary>
        /// Remove Display=None Code - for MSDN Documentation
        /// </summary>
		RemoveDisplayNone=256,

        /// <summary>
        /// Remove Size=0 tags
        /// </summary>
		RemoveSizeNone=512,

        /// <summary>
        /// Use HTTPDecode on HTML
        /// </summary>
		HTTPDecode=1024,

        /// <summary>
        /// Do not extract any images, just HTML, CSS, JS etc. - To speed up reading of document
        /// </summary>
        IgnoreImages=2048
	};

    /// <summary>
    /// 
    /// </summary>
	public interface IHelpFile
	{
        /// <summary>
        /// Occurs when [status handler event].
        /// </summary>
		event StatusHandler StatusHandlerEvent;
        /// <summary>
        /// Occurs when [progress handler event].
        /// </summary>
		event ProgressHandler ProgressHandlerEvent;

        /// <summary>
        /// Opens the specified system instance.
        /// </summary>
        /// <param name="systemInstance">The system instance.</param>
        /// <param name="chmFile">The CHM file.</param>
        /// <param name="Flags">The flags.</param>
        /// <param name="SH">The SH.</param>
        /// <param name="PH">The PH.</param>
        /// <returns></returns>
		bool				Open(IHelpSystem systemInstance, string chmFile, int Flags, StatusHandler SH, ProgressHandler PH);
        /// <summary>
        /// Closes this instance.
        /// </summary>
		void				Close();
        /// <summary>
        /// Sets the flags.
        /// </summary>
        /// <param name="Flags">The flags.</param>
        void                SetFlags(int Flags);

        /// <summary>
        /// Called when [progress].
        /// </summary>
        /// <param name="Value">The value.</param>
        /// <param name="MaxValue">The max value.</param>
		void				OnProgress(int Value,int MaxValue);
        /// <summary>
        /// Called when [progress].
        /// </summary>
        /// <param name="Value">The value.</param>
		void				OnProgress(int Value);
        /// <summary>
        /// Called when [status].
        /// </summary>
        /// <param name="Level">The level.</param>
        /// <param name="Text">The text.</param>
		void				OnStatus(int Level,string Text);
        /// <summary>
        /// Called when [status].
        /// </summary>
        /// <param name="Text">The text.</param>
		void				OnStatus(string Text);

        /// <summary>
        /// Gets or sets the help system.
        /// </summary>
        /// <value>The help system.</value>
		IHelpSystem			HelpSystem			{ get; set; }
        /// <summary>
        /// Gets or sets the text encoding.
        /// </summary>
        /// <value>The text encoding.</value>
		Encoding			TextEncoding		{ get; set; }

        /// <summary>
        /// Gets a value indicating whether this instance has table of contents.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has table of contents; otherwise, <c>false</c>.
        /// </value>
		bool				HasTableOfContents	{ get; }
        /// <summary>
        /// Gets the table of contents.
        /// </summary>
        /// <value>The table of contents.</value>
		TableOfContents		TableOfContents		{ get; }

        /// <summary>
        /// Gets a value indicating whether this instance has index.
        /// </summary>
        /// <value><c>true</c> if this instance has index; otherwise, <c>false</c>.</value>
		bool				HasIndex			{ get; }
        /// <summary>
        /// Gets the index.
        /// </summary>
        /// <value>The index.</value>
		Index				Index				{ get; }
        /// <summary>
        /// Gets the type of the help index.
        /// </summary>
        /// <value>The type of the help index.</value>
		IndexType			HelpIndexType		{ get; }

        /// <summary>
        /// Inits the search.
        /// </summary>
		void				InitSearch();
        /// <summary>
        /// Gets a value indicating whether this instance can search.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance can search; otherwise, <c>false</c>.
        /// </value>
		bool				CanSearch			{ get; }
        /// <summary>
        /// Performs the search.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
		SearchResultsTable	PerformSearch(string text);
        /// <summary>
        /// Matches the results.
        /// </summary>
        /// <param name="Hits">The hits.</param>
        /// <returns></returns>
		SearchResultsTable	MatchResults(SearchResultsTable Hits);
        /// <summary>
        /// Gets the F info.
        /// </summary>
        /// <value>The F info.</value>
		FileInfo			FInfo				{ get; }
        /// <summary>
        /// Gets the name of the file.
        /// </summary>
        /// <value>The name of the file.</value>
		string				FileName			{ get; }
        /// <summary>
        /// Gets the URL prefix.
        /// </summary>
        /// <value>The URL prefix.</value>
		string				UrlPrefix			{ get; }
        /// <summary>
        /// Gets the merge links.
        /// </summary>
        /// <value>The merge links.</value>
		ArrayList			MergeLinks			{ get; }	// List of TOCItem's to load		

        /// <summary>
        /// Finds the file.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		IFileInfo			FindFile(string FileName);
        /// <summary>
        /// Extracts the specified file info.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
		MemoryStream		Extract(IFileInfo fileInfo);
        /// <summary>
        /// Extrs the dact.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		MemoryStream		Extract(string FileName);
        /// <summary>
        /// Extracts as text.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
		string				ExtractAsText(IFileInfo fileInfo);
        /// <summary>
        /// Extracts as text.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		string				ExtractAsText(string FileName);

        /// <summary>
        /// Gets the number of files.
        /// </summary>
        /// <value>The number of files.</value>
		int					NumberOfFiles		{ get; }
        /// <summary>
        /// Processes all files.
        /// </summary>
        /// <param name="processAllFiles">The process all files.</param>
        /// <returns></returns>
		int 				ProcessAllFiles(ProcessAllFilesDelegate processAllFiles);
	}

    /// <summary>
    /// 
    /// </summary>
	public interface IHelpStream
	{
        /// <summary>
        /// Opens the specified file name.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <param name="helpFile">The help file.</param>
        /// <returns></returns>
		bool			Open(string FileName, IHelpFile helpFile);
        /// <summary>
        /// Closes this instance.
        /// </summary>
		void			Close();

        /// <summary>
        /// Finds the file.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		IFileInfo		FindFile(string FileName);
        /// <summary>
        /// Finds the file by ext.
        /// </summary>
        /// <param name="Ext">The ext.</param>
        /// <returns></returns>
		IFileInfo		FindFileByExt(string Ext);
        /// <summary>
        /// Extracts the specified file info.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
		MemoryStream	Extract(IFileInfo fileInfo);
        /// <summary>
        /// Extracts the specified file name.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
        /// <returns></returns>
		MemoryStream	Extract(string FileName);

        /// <summary>
        /// Gets the number of files.
        /// </summary>
        /// <value>The number of files.</value>
		int				NumberOfFiles	{ get; }
        /// <summary>
        /// Processes all files.
        /// </summary>
        /// <param name="processAllFiles">The process all files.</param>
        /// <returns></returns>
		int				ProcessAllFiles(ProcessAllFilesDelegate processAllFiles);
        /// <summary>
        /// Gets the name of the file.
        /// </summary>
        /// <value>The name of the file.</value>
		string			FileName		{ get; }
        /// <summary>
        /// Gets or sets the help file.
        /// </summary>
        /// <value>The help file.</value>
		IHelpFile		HelpFile		{ get; set; }
	}
}
